package com.cdn.agent.component;

import com.cdn.agent.IPrintLog;
import com.cdn.agent.enums.OrmType;
import com.mybatisflex.core.mybatis.FlexStatementHandler;
import com.mybatisflex.core.mybatis.SqlArgsParameterHandler;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Invocation;

import java.lang.reflect.Field;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;

/**
 * 蔡定努
 * 2024/08/27 13:28
 */
public class MybatisFlexLog extends IPrintLog {

    public MybatisFlexLog() {
        regist(this, OrmType.FLEX);
    }

    @Override
    public void printLog(Invocation invocation, long time) {
        try {
            FlexStatementHandler flexStatementHandler = (FlexStatementHandler) invocation.getTarget();
            BoundSql boundSql = flexStatementHandler.getBoundSql();
            showSql(boundSql, time, getMethod(flexStatementHandler));
        } catch (Exception ignore) {
        }
    }


    private String getMethod(FlexStatementHandler statementHandler) {
        try {
            SqlArgsParameterHandler parameterHandler = (SqlArgsParameterHandler) statementHandler.getParameterHandler();
            Class<?> superclass = parameterHandler.getClass().getSuperclass();
            Field mappedStatement1 = superclass.getDeclaredField("mappedStatement");
            mappedStatement1.setAccessible(true);
            MappedStatement o1 = (MappedStatement) mappedStatement1.get(parameterHandler);
            return o1.getId();
        } catch (Exception ignored) {
            return "";
        }
    }


    private void showSql(BoundSql boundSql, long time, String sqlId) {
        String sql = boundSql.getSql();
        Object parameterObject1 = boundSql.getParameterObject();
        Object[] parameterValue = getParameterValue(parameterObject1);

        String s = sql.replaceAll("\\?", "%s");
        String format = String.format(s, parameterValue) ;
        logs(time, format, sqlId);
    }

    private  Object[] getParameterValue(Object obj) {
        Object[] value;
        if (obj instanceof String) {
            value = new String[]{"'" + obj + "'"};
        } else if (obj instanceof Date) {
            DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
            value = new String[]{"'" + formatter.format(new Date()) + "'"};
        } else if (obj instanceof MapperMethod.ParamMap) {
            MapperMethod.ParamMap<?> obj1 = (MapperMethod.ParamMap<?>) obj;
            value = (Object[]) obj1.get("$$sql_args");
        } else {
            if (obj != null) {
                value = new String[]{"'" + obj + "'"};
            } else {
                value = new String[]{};
            }
        }
        return value;
    }
}
